[Feat]: Clean architecture#9
Merged
Merged
Conversation
- Introduced a new chat slice with a comprehensive service layer, including `ChatGateway` and `ChatService` for managing chat sessions, messages, and feedback. - Added UI components for chat history, message bubbles, and chat detail views, enhancing user interaction with chat transcripts. - Implemented functionality for loading chat messages, providing feedback, and exporting chat transcripts in various formats (JSON, Markdown, CSV). - Established a dependency injection plugin to provide the chat service throughout the application. This update lays the groundwork for a robust chat feature, allowing users to view, interact with, and manage their chat history effectively.
Mirror the chat slice's layering: extract the agent-send into a domain service + data gateway/mapper behind IBridleGateway, provided via a $bridleService DI plugin. The store keeps its reactive conversation state and localStorage persistence but no longer touches #api or unwrap. Also relocate unwrapEnvelope from #chat/data to #common/data so every slice's gateways share one envelope-peeling boundary (chat updated to import it from #common). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the same layering to the agent and auth slices: extract network
calls into domain services + data gateways/mappers behind IAgentGateway /
IAuthGateway, each provided via a DI plugin ($agentService / $authService).
Stores keep their reactive state (agent lists/current + loading/error;
auth token/user/hydration + localStorage + bearer wiring) but no longer
touch #api or unwrap.
Notes:
- agent remove(): pass the SDK-required query { wipeS3: 'false' }, which
also fixes a pre-existing type error and keeps deletes non-destructive.
- SDK/domain name collision (both AuthService): the data gateway imports
the SDK aliased as AuthApi.
- auth-init plugin now dependsOn 'auth-di' so $authService is provided
before init() -> me() runs at setup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mposable layers - Introduced a new error handling structure, including `ErrorEntity`, `ErrorMapper`, and `handleError` service for managing application errors. - Added utility functions for error handling and toast notifications. - Created composables for using error states in Vue components. - Updated Nuxt configuration to support the new error slice. - Established a clear separation of concerns between error data, domain logic, and UI components. This update enhances the application's error management capabilities, providing a more robust and user-friendly experience.
- Introduced `AuthCommonForm` component for handling both login and registration forms, including validation and error handling. - Created `Provider.vue` components for login and registration, integrating the common form and managing submission logic. - Enhanced user experience with dynamic feedback during form submission and error display. This update streamlines the authentication process, providing a unified interface for user login and registration.
Mirror the app's chat slice: extract the admin chat API into a domain service + data gateway/mapper behind IChatGateway, provided via a $chatService DI plugin. The store becomes a thin facade and no longer touches #api or unwrap. Adds the admin's own #common infra (BaseGateway, createServiceGetter, unwrapEnvelope). Admin specifics vs the app: list filters (IChatListQuery), on-demand summarize (keeps throwIfError for now), 6-role transcript incl. tool/system events, and IChatSession carrying agentId + summaryAt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…for ranch Adopt the shared #error error-handling system in the admin chat gateway: inject ErrorMapper via BaseGateway's super() and set throwOnError on summarizeChat so failures flow through the mapper (replaces the ad-hoc throwIfError helper) and surface as a typed ErrorEntity. Fix the ErrorMapper (both app + admin, ported from main-site's ofetch + FastAPI stack) for ranch's axios client + NestJS API: - read the error body from response.data (axios), not just response._data (ofetch); _data keeps precedence for compatibility. - surface NestJS's human-readable `message` verbatim when there's no FastAPI-style `detail`, instead of collapsing to a generic key. Brings the admin's #error slice under version control. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Migrate both stores of the agent/agent slice: - agent.ts (CRUD + lifecycle): extract behind IAgentGateway + AgentService, hiding the mixed transport (generated SDK, raw axios for stop/start/env/ metrics, raw fetch for the wipeS3 delete) and the rich failure handling (unwrapOrThrow) in the data layer. The store keeps the reactive agent list, optimistic status flips, and the localStorage restart flags. Also fixes a latent type error: logControllerGetLogs requires a `tail` query param. - agentStatus.ts (live SSE stream): follow main-site's subscription pattern (profileSubscription). The data gateway owns the EventSource and decodes frames via a mapper; the store keeps state + the reducer + consumer ref-counting. Provided as $agentStatusService alongside $agentService. Adds the agent slice's DI plugin + NuxtApp augmentation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the agent-channels API behind IAgentChannelGateway + AgentChannel service (provided as $agentChannelService); the store keeps only the per-agent cache + synchronous getCached. DTO mapping and envelope unwrapping move to the data layer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the agent-secrets API behind IAgentSecretGateway + AgentSecret service ($agentSecretService). Mutations return the refreshed list and throw the API's message on failure (moved into the gateway); the store keeps the reactive data/loading/error state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the agent file-workspace API behind IAgentFileGateway + AgentFile service ($agentFileService), including the raw-fetch ZIP export (gateway returns the Blob; the store triggers the download). The store keeps the reactive tree, the localStorage restart flags, and the save/delete node patching. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the templates API behind ITemplateGateway + TemplateService ($templateService): CRUD, setSkills/setMcps, and restartAgents (which hits the agent controller server-side, kept here so the store stays SDK-free). The store keeps the reactive list + mutations. Mapper converts the ITemplateResources interface to the DTO's index-signature shape. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the template file-workspace API behind ITemplateFileGateway + TemplateFile service ($templateFileService); the upload's folder-path derivation (webkitRelativePath) moves into the gateway. The store keeps the reactive tree + save node patching. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract template install (ZIP + git) behind ITemplateInstallGateway + TemplateInstall service ($templateInstallService). All transport moves to the gateway: raw multipart fetch for the archive endpoints (the SDK drops FormData), the SDK for git, plus the error handling. The store had no reactive state, so it's now a thin facade. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the LLM-credentials API behind ILlmGateway + LlmService ($llmService). The store keeps the reactive list/loading/error. Mapper coerces the domain's free `status: string` to the DTO's active|disabled union (fixes a latent type error). Static data/providers.ts is untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the MCP-servers API behind IMcpServerGateway + McpServerService ($mcpServerService). The store keeps the reactive list + mutations. Mapper coerces the generator-mistyped description/authValue (typed as objects, really nullable strings) at the DTO boundary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the integration-sessions API behind ISessionGateway + SessionService ($sessionService). The gateway uses the low-level SDK client (endpoints aren't in the generated SDK); the browser-mechanism filter moves into the service. The store keeps list/loading/error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the settings API behind ISettingGateway + SettingService ($settingService). The store keeps the reactive list plus the synchronous get/getValue lookups. Mapper casts the domain's `value: unknown` past the generator-mistyped DTO value field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the skills API behind ISkillGateway + SkillService ($skillService): CRUD, search, import from github/url, and dependent-agents lookup. The store keeps list/loading/error + the placeImported cache helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the per-agent usage API behind IUsageGateway + UsageService ($usageService). The store keeps the per-agent cache + synchronous getForAgent. SDK class aliased as UsageApi to avoid the name collision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the users API behind IUserGateway + UserService ($userService): CRUD + updateRoles. The store keeps the reactive list + mutations. Mapper casts the domain role/status enums past the generated wire enums (same values, different TS identity). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the API-keys API behind IApiKeyGateway + ApiKeyService ($apiKeyService). The store keeps list/loading/error + the created-key unshift. Mapper casts the domain scope enum past the wire enum. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract admin login/me behind IAuthGateway + AuthService ($authService); the SDK class of the same name is aliased AuthApi in the gateway. The store keeps the cookie-backed token, user, computeds, and the bearer wiring. The auth-init plugin now dependsOn 'auth-di' so $authService exists before hydrate() -> me() runs at setup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the Rancher bootstrap-status API behind IRancherGateway + RancherService ($rancherService). The store keeps the reactive status and patches the template in after ensureTemplate. SDK class aliased RancherApi. Domain reuses IAgentData/ITemplateData from the agent/template domains. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Migrate both paddock stores behind gateways + services: - paddockEvaluation → IPaddockEvaluationGateway + PaddockEvaluationService ($paddockEvaluationService): list/get/start/abort/rerun/report/trace, plus the raw-client logs/evalScenario routes. - paddockScenario → IPaddockScenarioGateway + PaddockScenarioService ($paddockScenarioService): CRUD + generate. Both provided from one DI plugin. Evaluations/scenarios are deeply nested opaque structures, so mappers are presence-validated casts. Stores keep the reactive lists + mutations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the knowledge-bases API behind IKnowledgeGateway + KnowledgeService ($knowledgeService): CRUD, index, query, graph, and the source operations (text/url/file/archive/sitemap — multipart via the raw axios instance, plus the raw-client /status route). The store keeps the reactive list + status/setup flags and composes startIndex. Mappers validate entities defensively; the opaque query-result/graph DTOs stay as #api passthroughs in the domain (documented exception). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cleaned up the Provider.vue component by removing unnecessary imports for Badge, Button, Input, Label, and Textarea, streamlining the code for better readability and performance.
- auth gateway: set throwOnError on login/me so a 401 propagates (as the
axios error) instead of the client silently yielding an empty session;
the login Provider's catch then shows the API's message ("Invalid
credentials"). Also lets hydrate() clear a stale/expired token.
- auth Form: add a show/hide password eye toggle and render the error as a
proper destructive alert box (matches the app's login form).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an axios response interceptor: on a 401 for any non-auth endpoint (expired / missing token, e.g. "Missing access token"), reset auth state via the store's logout() and redirect to /login. Login/register 401s are credential errors surfaced inline on the form, so those are excluded. logout() clears the store ref (not just the cookie) so the auth middleware sees "not authenticated" and doesn't bounce /login back to /agents. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cleaned up the Form.vue component by removing unnecessary imports for Button, Input, Label, and Card components, enhancing code readability and maintainability.
Mirror the admin's response interceptor: on a 401 for a non-auth endpoint (expired / missing token), reset auth state via the store's logout() and redirect to /login. All /auth/* endpoints are excluded — a login 401 is a credential error shown inline, and an init() /auth/me 401 is cleared silently by the auth store, so a returning visitor with a stale token still lands on the public pages (logged out) instead of being bounced to /login. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the app's token persistence from localStorage ('ranch.access_token')
to a 7-day, JS-readable `access_token` cookie via useCookie — same
convention as the admin. The Bearer header is still attached through
handleApiAuthentication; only the persistence layer changed. init() now
restores from the cookie-backed accessToken ref.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.